package classDAO;

import java.util.List;

import mappedClass.Task;
import mappedClass.Team;
import mappedClass.User;
import mappedClass.UserType;

import org.hibernate.Query;
import org.hibernate.Session;

import testhibernate.HibernateUtil;

public class UserDAO implements DAO {

	/**
	 * Find a user by the login
	 * 
	 * @param login
	 * @return User
	 */
	public User findByLogin(String login) {
		Session s = HibernateUtil.getSessionFactory().openSession();
		Query q = s.createQuery("FROM User u where u.login= :login").setString(
				"login", login);
		User u = (User) q.uniqueResult();
		s.close();
		return u;
	}

	public List findAll() {
		Session s = HibernateUtil.getSessionFactory().openSession();
		List list = s.createQuery("FROM User u").list();
		s.close();
		return list;
	}

	/** OK **/
	public Object getById(int id) {
		Session s = HibernateUtil.getSessionFactory().openSession();

		return (User) s.get(User.class, id);
	}

	/** OK **/
	public int getIdByName(String name) {
		Session s = HibernateUtil.getSessionFactory().openSession();

		Query q = s.createQuery("SELECT id FROM User u where u.login= :login")
				.setString("login", name);
		int id = (Integer) q.uniqueResult();
		return id;
	}

	/** OK **/
	/**
	 * Check if the user exists or not
	 * 
	 * @param login
	 * @param password
	 * @return boolean
	 */
	public boolean isUserPresent(String login, String password) {
		Session s = HibernateUtil.getSessionFactory().openSession();
		Query q = s
				.createQuery(
						"FROM User u WHERE u.login= :login AND u.password= :password")
				.setString("login", login).setString("password", password);
		User user = (User) q.uniqueResult();

		if (user != null) {
			System.out.println(user.getLogin() + "   " + user.getPassword());
			// MyVaadinUI.getCurrent().setCurrentuser(user);
			return true;
		}

		else
			return false;
	}

	/** OK **/
	/**
	 * Get the UserType to retrieve the name
	 * 
	 * @param login
	 * @return UserType
	 */
	public UserType getUserType(String login) {
		Session s = HibernateUtil.getSessionFactory().openSession();

		Query q = s.createQuery("FROM User u WHERE u.login= :login").setString(
				"login", login);

		User user = (User) q.uniqueResult();

		return user.getUsertype();
	}

	/**
	 * OK MAIS CHANGER LA METHODE QUAND LA TEAM N EXISTE PAS VOIR CE QU ON PEUT
	 * METTRE DANS CE CAS LA
	 **/
	/**
	 * Add user and associate it to a team
	 * 
	 * @param firstName
	 * @param lastName
	 * @param login
	 * @param password
	 * @param usertype
	 * @param email
	 * @param team
	 * @return boolean
	 */
	public boolean addUser(String firstName, String lastName, String login,
			String password, String usertype, String email, String team) {

		Session s = HibernateUtil.getSessionFactory().openSession();

		UserTypeDAO userTypeDAO = new UserTypeDAO();
		TeamDAO teamDAO = new TeamDAO();

		int idUserType = userTypeDAO.getIdByName(usertype);
		UserType userType = (UserType) userTypeDAO.getById(idUserType);
		User newUser = new User(userType, firstName, lastName, login, password,
				email);

		Query q = s
				.createQuery(
						"FROM User u, Team t WHERE u.login= :login AND t.name= :team")
				.setString("login", login).setString("team", team);

		List<Object[]> resultUserTeam = q.list();

		s.beginTransaction();

		s.save(newUser);

		if (resultUserTeam != null) {
			teamDAO.userTeamHistory(team, newUser, s);
		}

		else {
			Team newTeam = new Team(newUser, team);
			s.save(newTeam);

			teamDAO.userTeamHistory(team, newUser, s);
		}

		s.getTransaction().commit();
		s.close();

		return true;
	}

	/** OK **/
	/**
	 * Get the list of all user in a team
	 * 
	 * @param team
	 * @return List<User>
	 */
	public List<User> userByTeam(String team) {

		Session s = HibernateUtil.getSessionFactory().openSession();

		Query q = s.createQuery(
				"FROM User u "
						+ "WHERE id IN (SELECT user FROM UserTeamHistory "
						+ "WHERE "
						+ "teamId = (SELECT id FROM Team WHERE name= :team))")
				.setString("team", team);

		List<User> listUsers = q.list();

		return listUsers;
	}

	/** OK **/
	/**
	 * Get the list of user by team and task
	 * 
	 * @param nameTask
	 * @param team
	 * @return List<User>
	 */
	public List<User> userByTaskAndTeam(String nameTask, String team) {

		Session s = HibernateUtil.getSessionFactory().openSession();
		TaskDAO taskDAO = new TaskDAO();
		Task task = (Task) taskDAO.getById(taskDAO.getIdByName(nameTask));

		Query q = s
				.createQuery(
						"FROM User u "
								+ "WHERE id IN (SELECT ut.user FROM UserTask ut, UserTeamHistory "
								+ "WHERE ut.task= :task AND "
								+ "teamId = (SELECT id FROM Team WHERE name= :team))")
				.setParameter("task", task).setString("team", team);

		List<User> listUsers = q.list();

		return listUsers;

	}

	/** OK **/
	/**
	 * Get the list of user by task
	 * 
	 * @param nameTask
	 * @param team
	 * @return List<User>
	 */
	public List<User> userByTask(String nameTask) {

		Session s = HibernateUtil.getSessionFactory().openSession();
		TaskDAO taskDAO = new TaskDAO();
		Task task = (Task) taskDAO.getById(taskDAO.getIdByName(nameTask));

		Query q = s.createQuery(
				"FROM User u "
						+ "WHERE id IN (SELECT ut.user FROM UserTask ut "
						+ "WHERE ut.task= :task)").setParameter("task", task);

		List<User> listUsers = q.list();

		return listUsers;

	}

	/** OK **/
	/**
	 * Get the number of User for each UserType
	 * @param name
	 * @return Integer
	 */
	public int numberUsersByUserType(String name) {

		Session s = HibernateUtil.getSessionFactory().openSession();
		UserTypeDAO userTypeDAO = new UserTypeDAO();
		UserType userType = (UserType) userTypeDAO.getById(userTypeDAO
				.getIdByName(name));
		Query q = s.createQuery(
				"SELECT count(*) AS tot FROM User WHERE userTypeId= :userType")
				.setParameter("userType", userType);

		return ((Long)q.uniqueResult()).intValue();
	}
}

// public User getUser(String login) {
// try {
// if (MyVaadinUI.getCurrent().getCurrentuser().getLogin().equals(login)) {
// return MyVaadinUI.getCurrent().getCurrentuser();
// }
//
// User user;
// user = associateUserPM(login);
// return user;
// } catch (SQLException ex) {
// Logger.getLogger(UserManager.class.getName()).log(Level.SEVERE, null, ex);
// return null;
// }
//
// }
